package com.supsi.segretaria.server;
/*
 * User: Fabio Mastromatteo
 * Date: 06.05.12 - 07.06.12
 */

/**
 * Interprets the messages from the client and answers
 */
public class MessageInterpreter implements NewMessageEventListener{

    UserContainer userContainer=null;
    MessageQueue mq=null;
    ConnectionThread connectionThread;

    public MessageInterpreter(ConnectionThread connectionThread) {
        this.connectionThread=connectionThread;
    }

    /**
     * Gets the client string and answers
     * @param msgIn the string sent from the client
     * @return      the string to be sent to the client
     */
    public String inter(String msgIn){
        String msgOut="";

        String[] msgInArray=msgIn.split(" ");

        // user initialization
        // if the first communication is not an HELLO name, returns an error message
        if (msgInArray[0].equalsIgnoreCase("HELLO") && msgInArray.length>1 && userContainer==null){
            msgOut=hello(msgInArray[1]);
        } else if (userContainer==null) {
            msgOut="ERROR good manners are mandatory, can't compute: "+msgIn;
        //message management
        } else if (msgInArray[0].equalsIgnoreCase("GETMESSAGES") && msgInArray.length>1){
            msgOut=getMessages(msgInArray[1]);
        } else if (msgInArray[0].equalsIgnoreCase("MESSAGETO") && msgInArray.length>=3){
            msgOut=messageTo(msgIn, msgInArray);
        } else if (msgInArray[0].equalsIgnoreCase("DELMESSAGES") && msgInArray.length>1){
            msgOut=delMessages(msgInArray[1]);
        } else {
            msgOut="ERROR";
        }
        return msgOut+"\n";
    }

    /**
     * translates a message to an agreed transmission format
     */
    private String translator(Message message){
        return message.getUserFrom() +" | "+ message.getDate() +" | "+ message.getMessage()+"\n";//debug via \r
    }

    /**
     * initialize connection and notify for new messages
     */
    private String hello(String s){
        userContainer = MailSystem.getMailSystem().userConnected(s);
        mq = userContainer.getUserMq();
        userContainer.addNewMessageEventListener(this);
        int newMessages = mq.getUnreadMessagesNumber();
        if (newMessages==0) return "OK";
        else return "NEWMESSAGE "+newMessages;
    }

    /**
     * get the messages
     */
    private String getMessages(String s) {
        String out="";
        if (s.equalsIgnoreCase("new")) {
            if (mq.getUnreadMessagesNumber()==0){
                out= "INFO no new messages";
            } else {
                for (Message message:mq.getUnreadMessages()){
                    out+=translator(message);
                }
                out+="OK";
            }
            System.out.println(mq.getUnreadMessagesNumber());
        } else if (s.equalsIgnoreCase("all")) {
            if (mq.getAllMessagesNumber()==0) {
                out="INFO no messages";
            } else {
                for (Message message:mq.getAllMessages()){
                    out+=translator(message);
                }
                out+="OK";
            }
        } else out="ERROR";
        return out;
    }

    /**
     * stores a new message for another user
     * @param msgIn
     * @param msgInArray
     * @return
     */
    private String messageTo(String msgIn, String[] msgInArray){
        String usr = msgInArray[1];
        String msg = msgIn.substring(msgInArray[0].length()+msgInArray[1].length()+2);
        if (userContainer.sendMessage(usr,msg))
            return "OK";
        else
            return "ERROR message not sent";
    }

    /**
     * deletes one or all the messages
     * @param s
     * @return
     */
    private String delMessages(String s){
        Boolean success = false;
        String number = s;
        if (number.equalsIgnoreCase("all"))
            success = mq.delAllMessages();
        else
            success = mq.delMessage(Integer.parseInt(number));
        if (success)
            return "OK";
        else
             return "ERROR Deletion failed";
    }

    /**
     * inform userContainer and MailSystem the user is gone
     */
    public void close() {
        if (userContainer!=null){
            userContainer.removeNewMessageEventListener(this);
            MailSystem.getMailSystem().userDisconnected(userContainer);
        }
    }

    /**
     * notify a new message has been received
     * @param evt   event
     */
    @Override
    public void newMessageArrived(NewMessageEvent evt) {
        mq.refreshList();
        System.out.println("New message arrived");
        if (connectionThread!=null) connectionThread.notifyNewMessage(); // if implemented for the junit case
    }

    /**
     * manage the correct closure in case of connection lost
     */
    public void connectionLost(){
        if (userContainer!=null){
            System.out.println("Connection lost for user: "+userContainer.getUsername());
        } else {
            System.out.println("Connection lost for unknown user");
        }
        close();
    }
}
